﻿using Microsoft.AspNetCore.Mvc;
using MVC高级教程.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace MVC高级教程.Controllers
{
    /// <summary>
    /// 视图传值
    /// 本控制器及其视图，演示了视图传值的几种方法
    /// </summary>
    public class ViewValueTranController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }


        /**
            总结
                ①、ViewData和TempData是字典类型，赋值是按照字典的方式，   ViewData["Name"]
                ②、ViewBag是动态类型，使用时直接添加属性即可：     ViewBag.Name
                ③、ViewBag和ViewData只在当前Action中有效，声明和视图一个声明周期
                ④、ViewData和ViewBag中的值可以互相访问，因为ViewBag的实现中包含ViewData
        **/


        #region TempData 传递数据展示
        /// <summary>
        /// 演示TempData(临时数据类型)
        /// </summary>
        /// <returns></returns>
        public IActionResult IndexHello1()
        {
            List<Student1> list = new()
            {
                new(1,"余冰",32),
                new(2,"老赵",34),
                new(3,"老刘",35)
            };
            JArray jArray = new();
            foreach (var item in list)
            {
                JObject job = new();
                job.Add("Id", item.Id);
                job.Add("Name", item.Name);
                job.Add("Age", item.Age);
                jArray.Add(job);
            }


            //定义名为"StudentList"的临时数据
            TempData["StudentList"] = JsonConvert.SerializeObject(jArray);
            /**
                TempData保存在Session中，Controller每次执行请求的时候，会从Session中先获取TempData,而后清除session中的对应TempData
                获取完TempData数据，虽然保存在内部字典对象中，但是其集合中的每一个条目被访问完一次后就会从字典表中删除。
             * */
            return View();
        }
        #endregion


        #region ViewData 前后端传递数据演示
        /// <summary>
        /// ViewData数据传输演示
        /// ViewData只能在当前的Action中有效，其生命周一和视图生命周一相同
        /// </summary>
        /// <returns></returns>
        public IActionResult IndexHello2()
        {
            List<Student1> list = new()
            {
                new(1,"余冰",32),
                new(2,"老赵",34),
                new(3,"老刘",35)
            };

            ViewData["StudentList"] = list;

            return View();
        }
        #endregion


        #region ViewBag 前后端传递数据演示
        /// <summary>
        /// ViewBag 前后端数据传递演示
        /// ViewBag本质就是ViewData，只是多了层Dynamic控制。所以使用什么方式做前后端数据传递取决于你的爱好
        /// ViewBag的语法更符合面向对象的习惯
        /// </summary>
        /// <returns></returns>
        public IActionResult IndexHello3()
        {
            List<Student1> list = new()
            {
                new(1,"余冰",32),
                new(2,"老赵",34),
                new(3,"老刘",35)
            };

            ViewBag.StudentList = list;

            return View();//在合理直接通过View()方法，就是以ViewModel方式传值
        }
        #endregion


        #region ViewModel 的形式传值
        /// <summary>
        /// ViewModel传值
        /// </summary>
        /// <returns></returns>
        public IActionResult IndexHello4()
        {
            List<Student1> list = new()
            {
                new(1,"余冰",32),
                new(2,"老赵",34),
                new(3,"老刘",35)
            };
            ViewBag.StudentList = list;
            
            //1、如果你没有指定视图名称，则会食用当前Action名称作为视图名称
            //2、如果你指定视图名称，则会在当前控制器下匹配视图返回
            return View(list);
            // return View("IndexHello4")   根据视图名称输出视图
        }
        #endregion

        public IActionResult IndexHello5()
        {
            //指定视图名称(当前控制器下的视图)
            return View("IndexHello4");

            //如果你既想指定视图名称，又想通过ViewModel方式传递一个字符串到前台
            //可以用View()的重载：
            return View("IndexHello", "余冰");

            //指定其他控制器下的视图
            return View();
        }
    }
}
